package xyz.labmem.base.sys.module.auth.controller

import cn.dev33.satoken.stp.StpUtil
import xyz.labmem.base.sys.base.BaseController
import com.wf.captcha.SpecCaptcha
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import xyz.labmem.base.core.annotion.BusinessLog
import xyz.labmem.base.core.annotion.NoNeedLogin
import xyz.labmem.base.core.result.RV
import xyz.labmem.base.core.base.BaseVerify
import xyz.labmem.base.core.consts.REDIS_CAPTCHA
import xyz.labmem.base.core.enums.LogAnnotationOpTypeEnum
import xyz.labmem.base.sys.consts.PathPrefixConst
import xyz.labmem.base.sys.context.AuthRedisService
import xyz.labmem.base.sys.module.auth.controller.request.AdminAuthRequest
import xyz.labmem.base.sys.module.auth.controller.request.AuthRequest
import xyz.labmem.base.sys.module.auth.controller.request.AuthResetPwdRequest
import xyz.labmem.base.sys.module.auth.controller.response.AuthCaptchaRes
import xyz.labmem.base.sys.module.auth.service.AuthService
import xyz.labmem.base.sys.module.user.entity.SysUser
import xyz.labmem.base.sys.util.LogManager
import xyz.labmem.base.sys.util.RedisService
import java.util.*
import java.util.concurrent.TimeUnit


/**
 * 权限验证接口
 * @Author lty
 * @Date 2021/12/15 14:02
 */
@Api(tags = ["权限接口"])
@RestController
@RequestMapping(PathPrefixConst.AUTH_PATH_PREFIX)
class AuthController(
    private var passwordEncoder: PasswordEncoder,
    private var authRedisService: AuthRedisService,
    private var authService: AuthService,
    private var redisService: RedisService,
) : BaseController() {

    @NoNeedLogin
    @PostMapping("login")
    @ApiOperation(value = "登录")
    fun login(@RequestBody @Validated(BaseVerify.put::class) req: AuthRequest): RV<*> =
        authService.login(req, 0)

    @NoNeedLogin
    @PostMapping("admin/login")
    @ApiOperation(value = "管理员登录")
    fun adminLogin(@RequestBody @Validated(BaseVerify.put::class) req: AdminAuthRequest): RV<*> {
        if (redisService.isNotEmpty(REDIS_CAPTCHA + req.captchaKey!!)) {
            val code = redisService.get(REDIS_CAPTCHA + req.captchaKey)
            if (code == req.captcha!!.trim().lowercase(Locale.getDefault()))
                return authService.login(req, 1)
        }
        return failedMsg("验证码错误")
    }

    @PostMapping("logout")
    @ApiOperation(value = "注销")
    fun logout(): RV<Any> {
        LogManager.me().executeExitLog(getLoginUser().account)
    //    authRedisService.removeUserEntity(StpUtil.getLoginIdAsString(),StpUtil.getTokenValue())
        StpUtil.logout()
        return successMsg("good bye")
    }

    @NoNeedLogin
    @PostMapping("captcha")
    @ApiOperation(value = "获取验证码")
    fun captcha(): RV<*> {
        val specCaptcha = SpecCaptcha(130, 48, 5)
        val verCode = specCaptcha.text().lowercase(Locale.getDefault())
        val key = UUID.randomUUID().toString()
        redisService.add(REDIS_CAPTCHA + key, verCode, 10, TimeUnit.MINUTES)
        return success(AuthCaptchaRes().apply {
            captchaBase64 = specCaptcha.toBase64()
            captchaKey = key
        })
    }

    @BusinessLog(title = "修改密码", opType = LogAnnotationOpTypeEnum.UPDATE)
    @PostMapping("updatePwd")
    @ApiOperation(value = "自己修改密码")
    fun updatePwd(@RequestBody @Validated(BaseVerify.update::class) req: AuthResetPwdRequest): RV<Any> {
        val user = SysUser().selectById(StpUtil.getLoginIdAsString())
        if (passwordEncoder.matches(req.password, user.password)) {
            user.password = passwordEncoder.encode(req.newPassword)
            return resultJudgment(user.updateById())
        }
        return failedMsg("密码错误！")
    }

}